home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 31
/
Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso
/
Aminet
/
dev
/
c
/
vbccm68ksrc.lha
/
vbcc
/
vlink
/
t_elf32.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-03-07
|
59KB
|
1,836 lines
/* $VER: vlink t_elf32.c V0.6d (13.02.99)
*
* This file is part of vlink, a portable linker for multiple
* object formats.
* Copyright (c) 1997-99 Frank Wille
*
* vlink is freeware and part of the portable and retargetable ANSI C
* compiler vbcc, copyright (c) 1995-99 by Volker Barthelmann.
* vlink may be freely redistributed as long as no modifications are
* made and nothing is charged for it. Non-commercial usage is allowed
* without any restrictions.
* EVERY PRODUCT OR PROGRAM DERIVED DIRECTLY FROM MY SOURCE MAY NOT BE
* SOLD COMMERCIALLY WITHOUT PERMISSION FROM THE AUTHOR.
*
*
* v0.6d (13.02.98) phx
* The PowerUp ELF loader has its own constructor/destructor
* functionality and wildly mixes all words in .ctors and .dtors.
* Have to rename the sections to .ctor_/.dtor_ for elf32powerup
* executable generation.
* v0.6c (05.02.98) phx
* Constructor/destructor support for vbcc's _INIT/_EXIT
* function. The function pointers will be placed into the
* the .ctors and .dtors sections.
* v0.6a (19.12.98) phx
* Support for little endian object file formats.
* v0.6 (24.10.98) phx
* Standard ELF32 linker symbols _SDA_BASE_ and _SDA2_BASE_
* are supported. _SDA_BASE_ points to .sdata+0x7ff0 (or .sbss, if
* .sdata is missing) and _SDA2_BASE_ (EABI only) to .sdata2+0x7ff0.
* Take base register section offset from FFFuncs.baseoff. Each
* target defines their own offsets.
* .sdata/.sbss and .sdata2/.sbss2 will always be combined.
* Linking with shared objects is possible. Creating them is
* a another story...
* New target elf32powerup. It is a elf32ppcbe-type target, which
* uses relocatable objects as final executables. It is used for
* the Amiga PowerUp turbo boards from Phase5, which have a special
* ELF object loader. This loader will do some kind of dynamic
* linking with functions from the PowerUp kernel.
* _LinkerDB is no longer known to elf32ppcbe, but only to
* elf32powerup.
* v0.5d (22.08.98) phx
* Faster memory allocation can be activated by #define FASTALLOC.
* v0.5b (05.07.98) phx
* Linker symbol _LinkerDB for elf32ppcbe. _LinkerDB is a reloc sym-
* bol, which can be used to initialize a small data base register.
* v0.5 (27.06.98) phx
* Target-specific linker symbol support: elf32_lnksym(),
* elf32_setlnksym().
* v0.4 (05.06.98) phx
* New FFF targetlink(). Currently no meaning for ELF.
* v0.3b (25.04.98) phx
* Renamed from t_elf.c into t_elf32.c.
* v0.3 (17.04.98) phx
* First version, which links and writes ELF PowerPC 32Bit big
* endian objects (elf32ppcbe) reliable.
* v0.0 (21.03.98) phx
* File created.
*/
#if defined(ELF32_PPC_BE) || defined(ELF32_PPC_LE) || defined(ELF32_POWERUP)
#define T_ELF32_C
#include "vlink.h"
#include "elf32.h"
#include "rel_elfppc.h"
#define ELF_VER 1
#if defined(ELF32_PPC_BE) || defined(ELF32_POWERUP)
static int ppc32be_identify(char*,uint8 *,unsigned long);
static void ppc32be_readconv(struct GlobalVars *,struct LinkFile *);
static void ppc32be_readELF(struct GlobalVars *,struct LinkFile *,uint8 *);
static unsigned long ppc32be_secbase(struct GlobalVars *,char *);
static uint8 ppc32be_cmpsecflags(uint8,uint8);
static struct Section *ppc32be_bssdefault(struct ObjectUnit *);
static int ppc32be_targetlink(struct GlobalVars *,struct LinkedSection *,
struct Section *);
static struct Symbol *ppc32be_lnksym(struct GlobalVars *,struct Section *,
struct XReference *);
static void ppc32be_setlnksym(struct GlobalVars *,struct Symbol *,
struct XReference *);
static void ppc32be_relocs(struct GlobalVars *,uint8 *,struct ObjectUnit *,
struct Elf32_Shdr *);
#endif
#ifdef ELF32_PPC_BE
static void ppc32be_writeobject(struct GlobalVars *,FILE *);
static void ppc32be_writeshared(struct GlobalVars *,FILE *);
static void ppc32be_writeexec(struct GlobalVars *,FILE *);
static uint8 ppc32be_getrel(uint8,char *,uint32);
struct FFFuncs fff_elf32ppcbe = {
"elf32ppcbe",
ppc32be_identify,
ppc32be_readconv,
ppc32be_secbase,
ppc32be_cmpsecflags,
ppc32be_bssdefault,
ppc32be_targetlink,
ppc32be_lnksym,
ppc32be_setlnksym,
ppc32be_writeobject,
ppc32be_writeshared,
ppc32be_writeexec,
0x7ff0,
NULL,
1 /* big endian */
};
#endif
#ifdef ELF32_POWERUP
static struct Symbol *powerup_lnksym(struct GlobalVars *,struct Section *,
struct XReference *);
static void powerup_setlnksym(struct GlobalVars *,struct Symbol *,
struct XReference *);
static void powerup_writeobject(struct GlobalVars *,FILE *);
static void powerup_writeshared(struct GlobalVars *,FILE *);
static void powerup_writeexec(struct GlobalVars *,FILE *);
static uint8 powerup_getrel(uint8,char *,uint32);
struct FFFuncs fff_elf32powerup = {
"elf32powerup",
ppc32be_identify,
ppc32be_readconv,
ppc32be_secbase,
ppc32be_cmpsecflags,
ppc32be_bssdefault,
ppc32be_targetlink,
powerup_lnksym,
powerup_setlnksym,
powerup_writeobject,
powerup_writeshared,
powerup_writeexec,
0x7ff0,
NULL,
1 /* big endian */
};
/* elf32powerup linker symbols */
static char *linkerdb = "_LinkerDB";
#define LINKERDB 0 /* _LinkerDB, powerup */
#endif
/* elf32 common linker symbols */
static char *elf32_symnames[] = {
"_SDA_BASE_","_SDA2_BASE_",".ctors",".dtors"
};
/* number of elf32 linker symbols */
#define ELF32_LNKSYMS 4
/* Linker symbol IDs */
#define SDABASE 0 /* _SDA_BASE_, elf32 */
#define SDA2BASE 1 /* _SDA2_BASE_, elf32 */
#define CTORS 2 /* .ctors */
#define DTORS 3 /* .dtors */
/* small data sections */
static char *sdata = ".sdata";
static char *sbss = ".sbss";
static char *sdata2 = ".sdata2";
static char *sbss2 = ".sbss2";
/* automatic constructors and destructors (vbcc) */
static char vbcc_INIT[] = "_INIT";
static char vbcc_EXIT[] = "_EXIT";
static char xtors_objname[] = "INITEXIT"; /* unit name for con/destructors */
static int elf32be_identify(struct FFFuncs *,char *,struct Elf32_Ehdr *,
unsigned long,unsigned char,unsigned char,
uint16,uint32);
static void elf32be_check_ar_type(struct FFFuncs *,char *,
struct Elf32_Ehdr *,unsigned char,
unsigned char,uint32,uint16,uint16,uint16);
static char *elf32be_shstrtab(struct LinkFile *,struct Elf32_Ehdr *);
static char *elf32be_strtab(struct LinkFile *,struct Elf32_Ehdr *,int);
static struct Elf32_Sym *elf32be_symtab(struct LinkFile *,
struct Elf32_Ehdr *,int);
static struct Elf32_Shdr *elf32be_shdr(struct LinkFile *lf,
struct Elf32_Ehdr *,uint16);
static void elf32be_section(uint8 *,struct ObjectUnit *,
struct Elf32_Shdr *,int);
static int get_xtors_pri(char *);
static void elf32be_symbols(struct GlobalVars *,uint8 *,struct ObjectUnit *,
struct Elf32_Shdr *);
static void elf32be_reloc(struct GlobalVars *,struct Elf32_Ehdr *,
struct Section *,uint32,struct Elf32_Rela *,
bool,uint8);
static struct Section *elf32be_bssdefault(struct ObjectUnit *);
static int elf32_targetlink(struct GlobalVars *,struct LinkedSection *,
struct Section *);
static struct Symbol *elf32_lnksym(struct GlobalVars *,struct Section *,
struct XReference *,struct FFFuncs *);
static void elf32_setlnksym(struct GlobalVars *,struct Symbol *,
struct XReference *,struct FFFuncs *);
static void elf32be_header(FILE *,uint16,uint16,uint32,uint32,uint32,
uint32,uint16,uint16,uint16);
static void elf32be_writeshdrs(FILE *,uint32,uint32);
static void elf32be_stdsymtab(struct GlobalVars *,uint8,uint8);
static void